﻿namespace TestTool.GUI.Controls
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;
    using TestTool.GUI.Utils;
    using TestTool.GUI.Views;
    using TestTool.Tests.Definitions.Data;
    using TestTool.Tests.Definitions.Enums;
    using TestTool.Tests.Definitions.Interfaces;

    public class ProfilesTree : UserControl, IProfilesView
    {
        private Dictionary<Functionality, List<TreeNode>> _functionalityNodes;
        private List<TreeNode> _groupNodes;
        private bool _inactive;
        private Dictionary<IProfileDefinition, Dictionary<Functionality, TreeNode>> _profileFunctionalityNodes;
        private Dictionary<IProfileDefinition, TreeNode> _profileNodes;
        private Dictionary<string, List<TreeNode>> _scopeNodes;
        private const string ASSUMESUPPORTED = "NotTested";
        private IContainer components;
        private const string CONFIRMED = "Confirmed";
        private const string EXPECTED = "Expected";
        private const string FAILED = "NotSupported";
        private const string FEATURENOTSUPPORTED = "Feature not supported";
        private const string GROUP = "Group";
        private ImageList ilFunctionality;
        private const string NOFEATURE = "Optional feature not supported";
        private const string NOTCONFIRMED = "Not confirmed";
        private const string NOTESTS = "No tests were found for this functionality";
        private const string OPTIONALSCOPENOTSUPPORTED = "Skipped";
        private const string PROFILE_FAILED = "Profile not confirmed";
        private const string PROFILE_NOT_SUPPORTED = "Profile not supported";
        private const string PROFILE_SUPPORTED = "Profile supported";
        private const string PROFILEFAILED = "ProfileFailed";
        private const string PROFILENOTSUPPORTED = "ProfileNotSupported";
        private const string PROFILERCFAILED = "ProfileRcFailed";
        private const string PROFILERCNOTSUPPORTED = "ProfileRcNotSupported";
        private const string PROFILERCSUPPORTED = "ProfileRcSupported";
        private const string PROFILERCUNDEFINED = "ProfileRcUndefined";
        private const string PROFILESUPPORTED = "ProfileSupported";
        private const string PROFILEUNDEFINED = "ProfileUndefined";
        private const string SCOPENOTSUPPORTED = "NotSupported";
        private const string SCOPESUPPORTED = "Supported";
        private const string SCOPEUNDEFINED = "Undefined";
        private const string SELECTEDFORTEST = "Will be defined after selected tests are executed";
        private const string SKIPPED = "Skipped";
        private const string SUPPORTED = "Supported";
        private TreeView tvProfiles;
        private const string UNDEFINED = "Undefined";

        public event TreeViewCancelEventHandler BeforeSelect;

        public event Action<IProfileDefinition> ProfileSelected;

        public ProfilesTree()
        {
            this.InitializeComponent();
        }

        public void ClearAll()
        {
            this.ClearProfiles();
            foreach (List<TreeNode> list in this._scopeNodes.Values)
            {
                foreach (TreeNode node in list)
                {
                    this.SetImageKey(node, "Undefined");
                    node.ToolTipText = string.Empty;
                }
            }
        }

        public void ClearProfiles()
        {
            foreach (TreeNode node in this._profileNodes.Values)
            {
                IProfileDefinition tag = node.Tag as IProfileDefinition;
                if (tag.Status == ProfileVersionStatus.Release)
                {
                    this.SetImageKey(node, "ProfileUndefined");
                }
                else
                {
                    this.SetImageKey(node, "ProfileRcUndefined");
                }
                node.ToolTipText = string.Empty;
            }
            foreach (List<TreeNode> list in this._functionalityNodes.Values)
            {
                foreach (TreeNode node2 in list)
                {
                    this.SetImageKey(node2, "Undefined");
                    node2.ToolTipText = string.Empty;
                }
            }
        }

        public void DisplayFunctionalityToBeTested(List<Functionality> functionality)
        {
            Action method = () => this.RunForFunctionalityNodes(functionality, delegate (TreeNode node) {
                this.SetImageKey(node, "Expected");
                node.ToolTipText = "Will be defined after selected tests are executed";
            });
            base.BeginInvoke(method);
        }

        public void DisplayFunctionalityWithoutTestsInSuite(List<Functionality> functionality)
        {
            Action method = () => this.RunForFunctionalityNodes(functionality, delegate (TreeNode node) {
                this.SetImageKey(node, "NotTested");
                node.ToolTipText = "No tests were found for this functionality";
            });
            base.BeginInvoke(method);
        }

        public void DisplayMandatoryFunctionalityWithoutFeatures(Dictionary<IProfileDefinition, List<Functionality>> functionality)
        {
            Action method = delegate {
                foreach (IProfileDefinition definition in functionality.Keys)
                {
                    if (this._profileFunctionalityNodes.ContainsKey(definition))
                    {
                        foreach (Functionality functionality1 in functionality[definition])
                        {
                            if (this._profileFunctionalityNodes[definition].ContainsKey(functionality1))
                            {
                                TreeNode node = this._profileFunctionalityNodes[definition][functionality1];
                                this.SetImageKey(node, "NotSupported");
                                node.ToolTipText = "Feature not supported";
                            }
                        }
                    }
                }
            };
            base.BeginInvoke(method);
        }

        public void DisplayOptionalFunctionalityWithoutFeatures(Dictionary<IProfileDefinition, List<Functionality>> functionality)
        {
            Action method = delegate {
                foreach (IProfileDefinition definition in functionality.Keys)
                {
                    if (this._profileFunctionalityNodes.ContainsKey(definition))
                    {
                        foreach (Functionality functionality1 in functionality[definition])
                        {
                            if (this._profileFunctionalityNodes[definition].ContainsKey(functionality1))
                            {
                                TreeNode node = this._profileFunctionalityNodes[definition][functionality1];
                                this.SetImageKey(node, "Skipped");
                                node.ToolTipText = "Optional feature not supported";
                            }
                        }
                    }
                }
            };
            base.BeginInvoke(method);
        }

        public void DisplayProfiles(IEnumerable<IProfileDefinition> profiles)
        {
            this.tvProfiles.Nodes.Clear();
            this._scopeNodes = new Dictionary<string, List<TreeNode>>();
            this._functionalityNodes = new Dictionary<Functionality, List<TreeNode>>();
            this._profileNodes = new Dictionary<IProfileDefinition, TreeNode>();
            this._groupNodes = new List<TreeNode>();
            this._profileFunctionalityNodes = new Dictionary<IProfileDefinition, Dictionary<Functionality, TreeNode>>();
            foreach (IProfileDefinition definition in profiles)
            {
                TreeNode node = this.tvProfiles.Nodes.Add(definition.Name);
                if (definition.Status == ProfileVersionStatus.Release)
                {
                    this.SetImageKey(node, "ProfileUndefined");
                }
                else
                {
                    this.SetImageKey(node, "ProfileRcUndefined");
                }
                node.Tag = definition;
                this._profileNodes.Add(definition, node);
                Dictionary<Functionality, TreeNode> dictionary = new Dictionary<Functionality, TreeNode>();
                this._profileFunctionalityNodes.Add(definition, dictionary);
                TreeNode node2 = node.Nodes.Add(definition.Name + "Scopes", "Scopes");
                foreach (string str in definition.MandatoryScopes)
                {
                    string text = str;
                    TreeNode node3 = new TreeNode(text);
                    this.SetImageKey(node3, "Undefined");
                    node3.Tag = definition.MandatoryScopes.Contains<string>(str);
                    node2.Nodes.Add(node3);
                    if (!this._scopeNodes.ContainsKey(str))
                    {
                        this._scopeNodes.Add(str, new List<TreeNode>());
                    }
                    this._scopeNodes[str].Add(node3);
                }
                TreeNode node4 = node.Nodes.Add(definition.Name + "Functionality", "Functionality");
                this.SetImageKey(node4, "Group");
                foreach (FunctionalityItem item in definition.Functionalities)
                {
                    TreeNode node5 = this.FindGroupNode(node4, item.Path);
                    TreeNode node6 = new TreeNode(FunctionalityHelper.GetDisplayName(item.Functionality));
                    this.SetImageKey(node6, "Undefined");
                    node5.Nodes.Add(node6);
                    if (!this._functionalityNodes.ContainsKey(item.Functionality))
                    {
                        this._functionalityNodes.Add(item.Functionality, new List<TreeNode>());
                    }
                    this._functionalityNodes[item.Functionality].Add(node6);
                    dictionary.Add(item.Functionality, node6);
                }
            }
        }

        public void DisplayProfiles(IEnumerable<IProfileDefinition> supported, IEnumerable<IProfileDefinition> failed, IEnumerable<IProfileDefinition> notSupported)
        {
            Action method = delegate {
                foreach (IProfileDefinition definition in this._profileNodes.Keys)
                {
                    string imageKey = "Undefined";
                    string str2 = string.Empty;
                    bool flag = definition.Status == ProfileVersionStatus.ReleaseCandidate;
                    if (supported.Contains<IProfileDefinition>(definition))
                    {
                        imageKey = flag ? "ProfileRcSupported" : "ProfileSupported";
                        str2 = "Profile supported";
                    }
                    else if (failed.Contains<IProfileDefinition>(definition))
                    {
                        imageKey = flag ? "ProfileRcFailed" : "ProfileFailed";
                        str2 = "Profile not confirmed";
                    }
                    else
                    {
                        imageKey = flag ? "ProfileRcNotSupported" : "ProfileNotSupported";
                        str2 = "Profile not supported";
                    }
                    this.SetImageKey(this._profileNodes[definition], imageKey);
                    this._profileNodes[definition].ToolTipText = str2;
                }
            };
            base.BeginInvoke(method);
        }

        public void DisplayScope(string scope, bool supported)
        {
            base.BeginInvoke((Action)delegate {
                if (this._scopeNodes.ContainsKey(scope))
                {
                    foreach (TreeNode node in this._scopeNodes[scope])
                    {
                        bool tag = (bool) node.Tag;
                        this.SetImageKey(node, supported ? "Supported" : (tag ? "NotSupported" : "Skipped"));
                    }
                }
            });
        }

        public void DisplaySupportedFunctionality(Dictionary<Functionality, bool> functionality)
        {
            Action method = delegate {
                foreach (Functionality functionality1 in this._functionalityNodes.Keys)
                {
                    foreach (TreeNode node in this._functionalityNodes[functionality1])
                    {
                        if (functionality.ContainsKey(functionality1))
                        {
                            this.SetImageKey(node, functionality[functionality1] ? "Supported" : "NotSupported");
                            node.ToolTipText = functionality[functionality1] ? "Confirmed" : "Not confirmed";
                        }
                    }
                }
            };
            base.BeginInvoke(method);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private TreeNode FindGroupNode(TreeNode funcNode, string path)
        {
            string[] strArray = path.Split(new char[] { '\\' });
            string text = strArray[0];
            TreeNode node = null;
            foreach (TreeNode node2 in funcNode.Nodes)
            {
                if (node2.Name == text)
                {
                    node = node2;
                    break;
                }
            }
            if (node == null)
            {
                node = funcNode.Nodes.Add(text);
                node.Name = text;
                this.SetImageKey(node, "Group");
                this._groupNodes.Add(node);
            }
            if (strArray.Length == 1)
            {
                return node;
            }
            TreeNode node3 = node;
            string str2 = text;
            for (int i = 1; i < strArray.Length; i++)
            {
                string str3 = strArray[i];
                TreeNode node4 = null;
                foreach (TreeNode node5 in node3.Nodes)
                {
                    if (node5.Name == str3)
                    {
                        node4 = node5;
                        break;
                    }
                }
                str2 = str2 + @"\" + str3;
                if (node4 == null)
                {
                    node4 = node3.Nodes.Add(str3);
                    this.SetImageKey(node4, "Group");
                    this._groupNodes.Add(node4);
                    node4.Name = str3;
                }
                node3 = node4;
            }
            return node3;
        }

        private void InitializeComponent()
        {
            this.components = new Container();
            ComponentResourceManager manager = new ComponentResourceManager(typeof(ProfilesTree));
            this.tvProfiles = new TreeView();
            this.ilFunctionality = new ImageList(this.components);
            base.SuspendLayout();
            this.tvProfiles.Dock = DockStyle.Fill;
            this.tvProfiles.HideSelection = false;
            this.tvProfiles.ImageIndex = 0;
            this.tvProfiles.ImageList = this.ilFunctionality;
            this.tvProfiles.Location = new Point(0, 0);
            this.tvProfiles.Name = "tvProfiles";
            this.tvProfiles.SelectedImageIndex = 0;
            this.tvProfiles.ShowNodeToolTips = true;
            this.tvProfiles.Size = new Size(0x119, 0x1bd);
            this.tvProfiles.TabIndex = 0;
            this.tvProfiles.AfterSelect += new TreeViewEventHandler(this.tvProfiles_AfterSelect);
            this.tvProfiles.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.tvProfiles_NodeMouseClick);
            this.tvProfiles.BeforeSelect += new TreeViewCancelEventHandler(this.tvProfiles_BeforeSelect);
            this.ilFunctionality.ImageStream = (ImageListStreamer) manager.GetObject("ilFunctionality.ImageStream");
            this.ilFunctionality.TransparentColor = Color.Transparent;
            this.ilFunctionality.Images.SetKeyName(0, "Group");
            this.ilFunctionality.Images.SetKeyName(1, "ProfileUndefined");
            this.ilFunctionality.Images.SetKeyName(2, "ProfileSupported");
            this.ilFunctionality.Images.SetKeyName(3, "ProfileFailed");
            this.ilFunctionality.Images.SetKeyName(4, "ProfileNotSupported");
            this.ilFunctionality.Images.SetKeyName(5, "ProfileRcUndefined");
            this.ilFunctionality.Images.SetKeyName(6, "ProfileRcSupported");
            this.ilFunctionality.Images.SetKeyName(7, "ProfileRcFailed");
            this.ilFunctionality.Images.SetKeyName(8, "ProfileRcNotSupported");
            this.ilFunctionality.Images.SetKeyName(9, "Undefined");
            this.ilFunctionality.Images.SetKeyName(10, "Skipped");
            this.ilFunctionality.Images.SetKeyName(11, "NotTested");
            this.ilFunctionality.Images.SetKeyName(12, "Expected");
            this.ilFunctionality.Images.SetKeyName(13, "NotSupported");
            this.ilFunctionality.Images.SetKeyName(14, "Supported");
            base.AutoScaleDimensions = new SizeF(6f, 13f);
            base.AutoScaleMode = AutoScaleMode.Font;
            base.Controls.Add(this.tvProfiles);
            base.Name = "ProfilesTree";
            base.Size = new Size(0x119, 0x1bd);
            base.ResumeLayout(false);
        }

        private void RunForFunctionalityNodes(IEnumerable<Functionality> functionality, Action<TreeNode> action)
        {
            foreach (Functionality functionality2 in functionality)
            {
                if (this._functionalityNodes.ContainsKey(functionality2))
                {
                    foreach (TreeNode node in this._functionalityNodes[functionality2])
                    {
                        action(node);
                    }
                }
            }
        }

        private void SetImageKey(TreeNode node, string imageKey)
        {
            node.ImageKey = imageKey;
            node.SelectedImageKey = imageKey;
        }

        public void SetInactive()
        {
            this._inactive = true;
        }

        private void tvProfiles_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode parent = e.Node;
            if (parent != null)
            {
                while (parent.Parent != null)
                {
                    parent = parent.Parent;
                }
                IProfileDefinition tag = (IProfileDefinition) parent.Tag;
                if (this.ProfileSelected != null)
                {
                    this.ProfileSelected(tag);
                }
            }
        }

        private void tvProfiles_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if (this.BeforeSelect != null)
            {
                this.BeforeSelect(this, e);
            }
        }

        private void tvProfiles_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if ((this._inactive && (e.Node == this.tvProfiles.SelectedNode)) && this._inactive)
            {
                this._inactive = false;
                TreeNode parent = e.Node;
                if (parent != null)
                {
                    while (parent.Parent != null)
                    {
                        parent = parent.Parent;
                    }
                    IProfileDefinition tag = (IProfileDefinition) parent.Tag;
                    if (this.ProfileSelected != null)
                    {
                        this.ProfileSelected(tag);
                    }
                }
            }
        }
    }
}

